package Card.view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.List;
import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Observable;
import java.util.Observer;

import javax.swing.BoxLayout;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.border.BevelBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.SoftBevelBorder;

import Card.connect.CardClient;
import Card.game.Message;
import Card.game.Name;
import Card.game.Turn;

/**
 * Graphic user interface to play card game.
 * 
 * @author Juthamas Utamaphethai 5510546964
 * @author Natcha Chidbhob 5510546026
 * 
 */
public class CardUI extends JFrame implements Observer {
	/** contains messageField and send button. */
	private JPanel text;
	/** contains list and text panel. */
	private JPanel chat;
	/** contains pane and chat panel. */
	private JPanel bigPane;
	/** profile panel. */
	private JPanel prof;
	/** picture of player. */
	private JLabel pic;
	/** name of client. */
	private JLabel player;
	/** show text "money". */
	private JLabel lblMoney;
	/** show money of client. */
	private JLabel money;
	/** show my card. */
	private JLabel label1;
	/** show friend's card. */
	private JLabel label2;
	/** setting bet money. */
	private JTextField txtMoney;
	private JButton fold;
	private JButton fight;
	/** show messgae. */
	private List list;
	private TextField messageField;
	private CardClient card;
	private String Mycard;
	private JButton send;
	private Message message;
	/** all name of client. */
	private String[] name;
	private int countFold = 0;
	private int countLose = 0;
	private JLabel resultLabel;
	private java.net.URL imageURL;
	private ClassLoader cldr = this.getClass().getClassLoader();
	/** 
	 * Constructor of CardUI. 
	 * @param card of CardClient.
	 */
	public CardUI(CardClient card) {
		super("FUN GAME");
		this.card = card;
		initComponents();
	}
	/**
	 * contains all components.
	 */
	private void initComponents() {
		setDefaultCloseOperation(EXIT_ON_CLOSE);

		bigPane = new JPanel();
		BorderLayout big = new BorderLayout();
		bigPane.setLayout(big);

		imageURL = cldr.getResource("bg/flower.png");
		ImageIcon aceOfDiamonds = new ImageIcon(imageURL);
		ImagePanel pane = new ImagePanel(aceOfDiamonds.getImage());
		pane.setBackground(new Color(240, 240, 240));

		prof = new JPanel();
		prof.setBackground(Color.WHITE);
		prof.setBorder(new LineBorder(new Color(0, 128, 0), 2, true));
		pic = new JLabel("");

		player = new JLabel("Player");
		player.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblMoney = new JLabel("Money : ");
		lblMoney.setFont(new Font("Tahoma", Font.BOLD, 12));
		money = new JLabel(card.getMoney() + "");
		money.setFont(new Font("Tahoma", Font.BOLD, 12));
		GroupLayout gl_prof = new GroupLayout(prof);
		gl_prof.setHorizontalGroup(gl_prof
				.createParallelGroup(Alignment.TRAILING)
				.addGroup(
						gl_prof.createSequentialGroup()
								.addComponent(pic)
								.addGroup(
										gl_prof.createParallelGroup(
												Alignment.LEADING)
												.addGroup(
														gl_prof.createSequentialGroup()
																.addGap(10)
																.addComponent(
																		lblMoney)
																.addPreferredGap(
																		ComponentPlacement.RELATED)
																.addComponent(
																		money,
																		GroupLayout.DEFAULT_SIZE,
																		39,
																		Short.MAX_VALUE))
												.addGroup(
														gl_prof.createSequentialGroup()
																.addPreferredGap(
																		ComponentPlacement.RELATED)
																.addComponent(
																		player,
																		GroupLayout.DEFAULT_SIZE,
																		92,
																		Short.MAX_VALUE)))
								.addContainerGap()));
		gl_prof.setVerticalGroup(gl_prof
				.createParallelGroup(Alignment.LEADING)
				.addGroup(
						gl_prof.createSequentialGroup()
								.addGroup(
										gl_prof.createParallelGroup(
												Alignment.LEADING)
												.addGroup(
														gl_prof.createSequentialGroup()
																.addGap(21)
																.addComponent(
																		player)
																.addGap(18)
																.addGroup(
																		gl_prof.createParallelGroup(
																				Alignment.BASELINE)
																				.addComponent(
																						lblMoney)
																				.addComponent(
																						money)))
												.addComponent(pic))
								.addContainerGap(GroupLayout.DEFAULT_SIZE,
										Short.MAX_VALUE)));
		prof.setLayout(gl_prof);

		label1 = new JLabel();

		label2 = new JLabel();

		fight = new JButton("Fight");
		fight.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					if (txtMoney.getText().equals("")) {
						if (txtMoney.isEnabled())
							card.setBet(10);
						else
							card.setBet(0);
					} else {
						int a = Integer.parseInt(txtMoney.getText());
						if (a > 0 && a <= card.getMoney()) {
							card.setBet(a);
							System.out.println("a : " + a);
						} else if (a > card.getMoney()) {
							JOptionPane.showMessageDialog(null,
									"You don't have enough money.", "Error",
									JOptionPane.ERROR_MESSAGE);
							return;
						} else
							card.setBet(10);
					}
					txtMoney.setText("");
					txtMoney.setEnabled(false);
					card.sendToServer(card.getBetMoney());
					card.sendToServer("fight");
					fight.setEnabled(false);
					fold.setEnabled(false);
					message = new Message();
					message.setMessage("I'm FIGHT!!");
					card.sendToServer(message);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});
		fold = new JButton("Fold");
		fold.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				try {
					card.setBet(0);
					card.sendToServer(card.getBetMoney());
					card.sendToServer("fold");
					fight.setEnabled(false);
					fold.setEnabled(false);
					countFold++;
					message = new Message();
					message.setMessage("I'm FOLD!!");
					card.sendToServer(message);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		});

		txtMoney = new JTextField();
		txtMoney.setText("");

		txtMoney.setColumns(10);

		JLabel lblBet = new JLabel("Bet : ");
		lblBet.setFont(new Font("Tahoma", Font.BOLD, 15));
		lblBet.setForeground(new Color(51, 51, 255));

		resultLabel = new JLabel("");
		resultLabel.setFont(new Font("Tahoma", Font.BOLD, 25));
		resultLabel.setForeground(Color.RED);

		JLabel lblMyCard = new JLabel("My Card");
		lblMyCard.setForeground(new Color(153, 0, 153));
		lblMyCard.setFont(new Font("Tahoma", Font.BOLD, 15));

		GroupLayout gl_pane = new GroupLayout(pane);
		gl_pane.setHorizontalGroup(gl_pane
				.createParallelGroup(Alignment.LEADING)
				.addGroup(
						gl_pane.createSequentialGroup()
								.addGroup(
										gl_pane.createParallelGroup(
												Alignment.LEADING)
												.addGroup(
														gl_pane.createSequentialGroup()
																.addGap(50)
																.addGroup(
																		gl_pane.createParallelGroup(
																				Alignment.LEADING)
																				.addGroup(
																						gl_pane.createSequentialGroup()
																								.addComponent(
																										fight)
																								.addGap(30)
																								.addComponent(
																										fold)
																								.addGap(63)
																								.addComponent(
																										lblBet)
																								.addPreferredGap(
																										ComponentPlacement.UNRELATED)
																								.addComponent(
																										txtMoney,
																										GroupLayout.PREFERRED_SIZE,
																										GroupLayout.DEFAULT_SIZE,
																										GroupLayout.PREFERRED_SIZE)
																								.addGap(30)
																								.addComponent(
																										resultLabel))
																				.addGroup(
																						gl_pane.createSequentialGroup()
																								.addComponent(
																										label1)
																								.addGap(70)
																								.addComponent(
																										label2))))
												.addComponent(
														prof,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addGroup(
														gl_pane.createSequentialGroup()
																.addGap(84)
																.addComponent(
																		lblMyCard)))
								.addContainerGap(262, Short.MAX_VALUE)));
		gl_pane.setVerticalGroup(gl_pane
				.createParallelGroup(Alignment.LEADING)
				.addGroup(
						gl_pane.createSequentialGroup()
								.addComponent(prof, GroupLayout.PREFERRED_SIZE,
										96, GroupLayout.PREFERRED_SIZE)
								.addGap(19)
								.addComponent(lblMyCard)
								.addPreferredGap(ComponentPlacement.RELATED)
								.addGroup(
										gl_pane.createParallelGroup(
												Alignment.BASELINE)
												.addComponent(label2)
												.addComponent(label1))
								.addGap(40)
								.addGroup(
										gl_pane.createParallelGroup(
												Alignment.BASELINE)
												.addComponent(
														fight,
														GroupLayout.PREFERRED_SIZE,
														31,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														fold,
														GroupLayout.PREFERRED_SIZE,
														31,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(
														txtMoney,
														GroupLayout.PREFERRED_SIZE,
														GroupLayout.DEFAULT_SIZE,
														GroupLayout.PREFERRED_SIZE)
												.addComponent(lblBet)
												.addComponent(resultLabel))
								.addGap(20)));
		pane.setLayout(gl_pane);
		chat = new JPanel();
		text = new JPanel();
		chat.setBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null,
				null, null));
		chat.setLayout(new BoxLayout(chat, BoxLayout.Y_AXIS));
		text.setLayout(new BoxLayout(text, BoxLayout.X_AXIS));
		list = new List();
		messageField = new TextField();
		send = new JButton("SEND");
		Font messageFont = new Font(Font.DIALOG_INPUT, Font.PLAIN, 18);
		list.setFont(messageFont);
		chat.add(list);
		text.add(messageField);
		text.add(send);
		chat.add(text);
		messageField.addActionListener(messageActionListener);
		send.addActionListener(messageActionListener);

		imageURL = cldr.getResource("image/ques.jpg");
		ImageIcon pic = new ImageIcon(imageURL);
		label1.setIcon(pic);

		bigPane.add(chat, BorderLayout.SOUTH);
		bigPane.add(pane, BorderLayout.CENTER);
		getContentPane().add(bigPane);

	}
	/**
	 * run the program.
	 */
	public void run() {
		pack();
		setSize(490, 580);
		setResizable(false);
		setVisible(true);
	}
	/**
	 * action of messageFile and send button
	 * it will send message to server.
	 */
	ActionListener messageActionListener = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
			message = new Message();
			message.setMessage(messageField.getText());
			try {
				card.sendToServer(message);
				messageField.setText("");
			} catch (Exception ex) {
				list.add(ex.toString());
				list.makeVisible(list.getItemCount() - 1);
				list.setBackground(Color.yellow);
			}
		}
	};

	@Override
	public void update(Observable o, Object arg) {
		int all = 0;
		if (card.getMoney() < 0 && countLose == 0) {
			try {
				System.out.println("send lose");
				String[] lo = { "lose", card.getID() + "" };
				card.sendToServer(lo);
			} catch (IOException e) {
				e.printStackTrace();
			}
			fight.setEnabled(false);
			fold.setEnabled(false);
			txtMoney.setEnabled(false);
			money.setText("Bankrupt");
			money.setForeground(Color.RED);
		}
		if (arg instanceof Turn) {
			Turn turn = (Turn) arg;
			if (turn == Turn.p1 && card.getID() == 1) {
				txtMoney.setText("10");
				txtMoney.setEnabled(true);
			} else if (turn == Turn.p2 && card.getID() == 2) {
				txtMoney.setText("10");
				txtMoney.setEnabled(true);
			} else {
				txtMoney.setEnabled(false);
				txtMoney.setText("");
			}
		}
		if (arg instanceof Name) {
			Name na = (Name) arg;
			name = na.getAll();
			player.setText(name[card.getID() - 1]);
			if (card.getID() == 1) {
				imageURL = cldr.getResource("bg/play.jpg");
				ImageIcon picPro = new ImageIcon(imageURL);
				pic.setIcon(picPro);
			} else {
				imageURL = cldr.getResource("bg/play3.jpg");
				ImageIcon picPro = new ImageIcon(imageURL);
				pic.setIcon(picPro);
			}
		}
		if (arg instanceof Byte) {
			Byte count = (Byte) arg;
			all = count;
		}
		if (arg instanceof int[]) {
			money.setText(card.getMoney() + "");
		}
		if (arg instanceof String[]) {
			String[] c = (String[]) arg;
			if (c[0].equals("winner") && countLose == 0) {
				if (c[1].equals(card.getID() + "")) {
					countLose++;
					JOptionPane.showMessageDialog(this, "LOSE", "result",
							JOptionPane.WARNING_MESSAGE);
				} else {
					countLose++;
					imageURL = cldr.getResource("bg/icon.png");
					ImageIcon icon = new ImageIcon(imageURL);
					JOptionPane.showMessageDialog(this, "WINNER.", "result",
							JOptionPane.INFORMATION_MESSAGE, icon);

				}
				int n = JOptionPane.showConfirmDialog(this,
						"Would you like to replay again?", "Question",
						JOptionPane.YES_NO_OPTION);
				if (n == JOptionPane.YES_OPTION) {
					try {
						card.sendToServer("yes");
					} catch (IOException e) {
						e.printStackTrace();
					}
				} else {
					System.exit(0);
				}
			}
			if (c[0].equals("card")) {
				for (int i = 1; i < c.length; i++) {
					imageURL = cldr.getResource(String.format("image/%s.jpg",
							c[i]));
					ImageIcon pic = new ImageIcon(imageURL);
					if (i == 1) {
						Mycard = c[1];
					}
					if (i == 2) {
						label2.setIcon(pic);
					}
				}

			}
		}
		if (arg instanceof Message) {
			Message mess = (Message) arg;
			String[] word = mess.getClientMess();
			if (word[1].equals("has disconnected !!")) {
				JOptionPane.showMessageDialog(this, word[0] + " " + word[1],
						"Disconnect", JOptionPane.WARNING_MESSAGE);
				System.exit(0);
			}
			list.add(word[0] + " : " + word[1]);
			list.makeVisible(list.getItemCount() - 1);
		}
		if (arg instanceof String) {
			String ms = arg.toString();
			if (ms.equals("clear")) {
				try {
					card.setInitMoney(100, 0);
					card.setBet(10);
				} catch (IOException e1) {
					e1.printStackTrace();
				}
				money.setText(card.getMoney() + "");
				// money.setText("100");
				countFold = 0;
				countLose = 0;
				money.setForeground(Color.BLACK);
				fight.setEnabled(true);
				fold.setEnabled(true);
				imageURL = cldr.getResource("image/ques.jpg");
				ImageIcon pic = new ImageIcon(imageURL);
				label1.setIcon(pic);

				label2.setText("");
				try {
					if (card.getID() == 1)
						card.sendToServer("send card");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (ms.equals("result")) {
				imageURL = cldr.getResource(String.format("image/%s.jpg",
						Mycard));
				ImageIcon picLabel1 = new ImageIcon(imageURL);
				label1.setText("");
				label1.setIcon(picLabel1);

				Thread th = Thread.currentThread();
				try {
					th.sleep(3000);
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}

				imageURL = cldr.getResource(String.format("image/%s.jpg",
						"ques"));
				picLabel1 = new ImageIcon(imageURL);
				label1.setIcon(picLabel1);
				if (card.getMoney() == 0) {
					String[] lo = { "lose", card.getID() + "" };
					try {
						card.sendToServer(lo);
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				if (card.getID() == 1) {
					try {
						card.sendToServer("send card");
					} catch (IOException e) {
						e.printStackTrace();
					}
				}
				fight.setEnabled(true);
				if (countFold < 3)
					fold.setEnabled(true);

			}
			if (ms.equals("give me a money")) {
				fight.setEnabled(false);
				fold.setEnabled(false);
			}
		}
	}
}
